////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file camxthreadjoblist.h
///
/// @brief Provides container for runtime jobs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXTHREADJOBLIST_H
#define CAMXTHREADJOBLIST_H

#include "camxtypes.h"
#include "camxosutils.h"
#include "camxthreadcommon.h"
#include "camxthreadjobregistry.h"

CAMX_NAMESPACE_BEGIN

/// @brief A slot in the runtime JobList
struct JobSlot
{
    UINT32  slot;   ///< this slot
    UINT32  next;   ///< pointer to the next available slot
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief JobList holds and keeps track of all submitted jobs in the thread library
///
/// JobList holds and keeps track of all submitted jobs in the thread library
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class JobList
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// JobList
    ///
    /// @brief  Constructor for JobList object
    ///
    /// @param  pJobRegistry Pointer to the job registry
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    explicit JobList(
        JobRegistry* pJobRegistry);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~JobList
    ///
    /// @brief  Destructor for JobList object
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ~JobList();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// AcquireJobEntry
    ///
    /// @brief  Fits a runtime job into the job list
    ///
    /// @param  hJob Handle of the incoming runtime job
    ///
    /// @return Pointer to an empty RuntimeJob or NULL
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    RuntimeJob* AcquireJobEntry(
        JobHandle hJob);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ReleaseJobEntry
    ///
    /// @brief  Releases a runtime job from the job list after it finished execution or was stopped
    ///
    /// @param  pJob    Pointer to the runtime job
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID ReleaseJobEntry(
        RuntimeJob* pJob);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Initialize
    ///
    /// @brief  Initialize a newly created JobList object
    ///
    /// @return Success if successful, an error code otherwise
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult Initialize();

private:
    JobRegistry*    m_pJobRegistry;              ///< Cache the job registry
    RuntimeJob      m_jobList[MaxRuntimeJobs];   ///< Container of runtime jobs

    UINT32          m_freeHead;                  ///< Head of free slot list
    UINT32          m_freeTail;                  ///< Tail of free slot list
    JobSlot         m_freeList[MaxRuntimeJobs];  ///< List of free slots

    UINT32          m_jobOccupancy;              ///< Current job occupancy in the list
    Mutex*          m_pListLock;                 ///< Job List lock

    // Disable copy constructor and assignment operator
    JobList(const JobList&) = delete;
    JobList& operator=(const JobList&) = delete;
};

CAMX_NAMESPACE_END

#endif // CAMXTHREADJOBLIST_H
